package com.turman.composebook.views

import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.Call
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.Email
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Menu
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material.icons.filled.Refresh
import androidx.compose.material.icons.filled.Send
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material.icons.rounded.Call
import androidx.compose.material.icons.rounded.MoreVert
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ScrollableTabRow
import androidx.compose.material3.Surface
import androidx.compose.material3.Tab
import androidx.compose.material3.TabPosition
import androidx.compose.material3.TabRow
import androidx.compose.material3.TabRowDefaults
import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.debugInspectorInfo
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.turman.composebook.ui.theme.backgroundColor

data class ActionItemSpec(
    val name: String,
    val icon: ImageVector,
    val visibility: ActionItemMode = ActionItemMode.IF_ROOM,
    val onClick: () -> Unit,
)

enum class ActionItemMode {
    ALWAYS_SHOW, IF_ROOM, NEVER_SHOW
}

@Composable
fun TopAppBarSampleView(modifier: Modifier = Modifier) {
    LazyColumn(
        modifier = modifier
            .fillMaxSize()
            .background(backgroundColor),
        contentPadding = PaddingValues(8.dp),
        verticalArrangement = Arrangement.spacedBy(8.dp),
        content = {

            item {
                StyleableTutorialText(
                    text = "1-) TopAppbar with IconButtons as Toolbar menus in classic Views"
                )
            }
            item {
                ActionTopAppbar(null, elevation = 8.dp)
            }
            item {
                StyleableTutorialText(
                    text = "2-) TopAppbar with Overflow menu"
                )
            }
            item {
                OverflowTopAppBar()
            }

            item {
                OverflowTopAppBar2()
            }

            item {
                StyleableTutorialText(
                    text = "3-) Fixed tabs only with text. **TabRow** is our fixed Row with equal size for each tab that contains tabs."
                )
            }
            item {
                TextTabComponent()
            }

            item {
                StyleableTutorialText(
                    text = "4-) Fixed tabs only with icon"
                )
            }
            item {
                IconTabComponent()
            }

            item {
                StyleableTutorialText(
                    text = "5-) Fixed tabs with text and icon"
                )
            }
            item {
                CombinedTabComponent()
            }

            item {
                StyleableTutorialText(
                    text = "6-) Fixed tabs with horizontally placed text and icon"
                )
            }
            item {
                CombinedTabComponent2()
            }
            item {
                StyleableTutorialText(
                    text = "7-) Scrollable tabs"
                )
            }
            item {
                ScrollableTextTabComponent()
            }
            item {
                StyleableTutorialText(
                    text = "8-) Custom tabs"
                )
            }
            item {
                CustomTabs()
            }

            item {
                StyleableTutorialText(
                    text = "9-) TopAppBar and Tabs"
                )
            }
            item {
                TopAppBarWithTabComponent(null)
            }

            item {
                StyleableTutorialText(
                    text = "10-) Whatsapp TopAppbar"
                )
            }
            item {
                ChatAppbar(
                    title = "Custom Chat",
                    description = "Alice, Brook, Jack, Jason, Brad, No Name User"
                )
            }
        })
}

@Composable
fun TutorialContent(onBack: (() -> Unit)? = null) {
    LazyColumn(
        modifier = Modifier
            .fillMaxSize()
            .background(backgroundColor),
        contentPadding = PaddingValues(8.dp),
        verticalArrangement = Arrangement.spacedBy(8.dp),
        content = {

            item {
                StyleableTutorialText(
                    text = "1-) TopAppbar with IconButtons as Toolbar menus in classic Views"
                )
            }
            item {
                ActionTopAppbar(onBack, elevation = 8.dp)
            }
            item {
                StyleableTutorialText(
                    text = "2-) TopAppbar with Overflow menu"
                )
            }
            item {
                OverflowTopAppBar()
            }

            item {
                OverflowTopAppBar2()
            }

            item {
                StyleableTutorialText(
                    text = "3-) Fixed tabs only with text. **TabRow** is our fixed Row with equal size for each tab that contains tabs."
                )
            }
            item {
                TextTabComponent()
            }

            item {
                StyleableTutorialText(
                    text = "4-) Fixed tabs only with icon"
                )
            }
            item {
                IconTabComponent()
            }

            item {
                StyleableTutorialText(
                    text = "5-) Fixed tabs with text and icon"
                )
            }
            item {
                CombinedTabComponent()
            }

            item {
                StyleableTutorialText(
                    text = "6-) Fixed tabs with horizontally placed text and icon"
                )
            }
            item {
                CombinedTabComponent2()
            }
            item {
                StyleableTutorialText(
                    text = "7-) Scrollable tabs"
                )
            }
            item {
                ScrollableTextTabComponent()
            }
            item {
                StyleableTutorialText(
                    text = "8-) Custom tabs"
                )
            }
            item {
                CustomTabs()
            }

            item {
                StyleableTutorialText(
                    text = "9-) TopAppBar and Tabs"
                )
            }
            item {
                TopAppBarWithTabComponent(onBack)
            }

            item {
                StyleableTutorialText(
                    text = "10-) Whatsapp TopAppbar"
                )
            }
            item {
                ChatAppbar(
                    title = "Custom Chat",
                    description = "Alice, Brook, Jack, Jason, Brad, No Name User",
                    onBack = onBack
                )
            }
        })
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun OverflowTopAppBar() {

    var showMenu by remember { mutableStateOf(false) }

    TopAppBar(
        title = { Text("Overflow") },
        actions = {
            IconButton(onClick = { /*TODO*/ }) {
                Icon(Icons.Default.Favorite, contentDescription = null)
            }
            IconButton(onClick = { showMenu = !showMenu }) {
                Icon(Icons.Default.MoreVert, contentDescription = null)
            }
            DropdownMenu(
                expanded = showMenu,
                onDismissRequest = { showMenu = false }
            ) {
                DropdownMenuItem(onClick = { showMenu = !showMenu }, text = {
                    Icon(Icons.Filled.Refresh, contentDescription = null)
                })
                DropdownMenuItem(
                    onClick = { showMenu = !showMenu },
                    text = { Icon(Icons.Filled.Call, contentDescription = null) })
            }
        }
    )
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun OverflowTopAppBar2() {
    val items = listOf(
        ActionItemSpec("Call", Icons.Default.Call, ActionItemMode.ALWAYS_SHOW) {},
        ActionItemSpec("Send", Icons.Default.Send, ActionItemMode.IF_ROOM) {},
        ActionItemSpec("Email", Icons.Default.Email, ActionItemMode.IF_ROOM) {},
        ActionItemSpec("Delete", Icons.Default.Delete, ActionItemMode.IF_ROOM) {},
    )
    TopAppBar(
        title = { Text("Overflow2") },
        navigationIcon = {
            IconButton(onClick = {}) {
                Icon(Icons.Default.Menu, "Menu")
            }
        },
        actions = {
            ActionMenu(items, defaultIconSpace = 3)
        }
    )
}

@Composable
fun ActionMenu(
    items: List<ActionItemSpec>,
    defaultIconSpace: Int = 3, // includes overflow menu
    menuExpanded: MutableState<Boolean> = remember { mutableStateOf(false) }
) {
    // decide how many ifRoom icons to show as actions
    val (actionItems, overflowItems) = remember(items, defaultIconSpace) {
        separateIntoActionAndOverflow(items, defaultIconSpace)
    }

    Row {
        for (item in actionItems) {
            IconButton(onClick = item.onClick) {
                Icon(item.icon, item.name)
            }
        }
        if (overflowItems.isNotEmpty()) {
            IconButton(onClick = { menuExpanded.value = true }) {
                Icon(Icons.Default.MoreVert, "More actions")
            }
            DropdownMenu(
                expanded = menuExpanded.value,
                onDismissRequest = { menuExpanded.value = false }
            ) {
                for (item in overflowItems) {
                    DropdownMenuItem(onClick = item.onClick, text = {
                        Text(item.name)
                    })
                }
            }
        }
    }
}


@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ActionTopAppbar(onBack: (() -> Unit)? = null, elevation: Dp) {
    TopAppBar(
        title = {
            Text(text = "TopAppBar")
        },
//        elevation = 8.dp,
        colors = TopAppBarDefaults.smallTopAppBarColors(
            containerColor = MaterialTheme.colorScheme.surface,
            titleContentColor = MaterialTheme.colorScheme.onSecondary
        ),
        navigationIcon = {
            IconButton(onClick = { onBack?.invoke() }) {
                Icon(
                    imageVector = Icons.Filled.ArrowBack,
                    contentDescription = null
                )
            }
        },
        actions = {
            IconButton(onClick = { /* doSomething() */ }) {
                Icon(Icons.Filled.Favorite, contentDescription = null)
            }

            IconButton(onClick = { /* doSomething() */ }) {
                Icon(Icons.Filled.Refresh, contentDescription = null)
            }

            IconButton(
                onClick = { /* doSomething() */ }) {
                Icon(Icons.Filled.Call, contentDescription = null)
            }
        }
    )
}

@Composable
fun TextTabComponent() {
    var selectedIndex by remember { mutableStateOf(0) }

    val list = listOf("Home", "Map Screen", "Settings")

    TabRow(selectedTabIndex = selectedIndex,
        indicator = { tabPositions: List<TabPosition> ->

            tabPositions.forEachIndexed { index, tabPosition ->
                println(
                    "index: $index, " +
                            "left: ${tabPosition.left}, " +
                            "right: ${tabPosition.right}, " +
                            "width: ${tabPosition.width}"
                )
            }

            Box(
                modifier = Modifier
                    .myTabIndicatorOffset(tabPositions[selectedIndex])
                    .height(4.dp)
                    .background(color = Color.Red)
            ) {}
        }) {
        list.forEachIndexed { index, text ->
            Tab(selected = selectedIndex == index,
                onClick = { selectedIndex = index },
                text = { Text(text = text) }
            )
        }
    }
}

@Composable
fun IconTabComponent() {

    var selectedIndex by remember { mutableStateOf(0) }
    val icons = listOf(Icons.Filled.Home, Icons.Default.Home, Icons.Filled.Settings)
    TabRow(
        selectedTabIndex = selectedIndex,
        containerColor = Color(0xff546E7A),
        contentColor = Color(0xffF06292),
//            divider = {
//                TabRowDefaults.Divider(
//                    thickness = 5.dp,
//                    color = Color(0xffE0E0E0)
//                )
//            },
        indicator = { tabPositions: List<TabPosition> ->
            TabRowDefaults.Indicator(
                modifier = Modifier.tabIndicatorOffset(tabPositions[selectedIndex]),
                height = 5.dp,
                color = Color(0xff8BC34A)
            )
        }
    ) {
        icons.forEachIndexed { index, imageVector ->
            Tab(
                selected = selectedIndex == index,
                onClick = { selectedIndex = index },
                icon = {
                    Icon(imageVector = imageVector, contentDescription = null)
                })
        }
    }
}

@Composable
fun CombinedTabComponent() {

    var selectedIndex by remember { mutableStateOf(0) }
    val tabContents = listOf(
        "Home" to Icons.Filled.Home,
        "Map" to Icons.Filled.Menu,
        "Settings" to Icons.Filled.Settings
    )

    TabRow(
        selectedTabIndex = selectedIndex,
        containerColor = MaterialTheme.colorScheme.surface,
        contentColor = MaterialTheme.colorScheme.onSurface,
    ) {
        tabContents.forEachIndexed { index, pair: Pair<String, ImageVector> ->
            Tab(selected = selectedIndex == index, onClick = { selectedIndex = index },
                text = { Text(text = pair.first) },
                icon = { Icon(imageVector = pair.second, contentDescription = null) }
            )
        }
    }
}

@Composable
fun CombinedTabComponent2() {

    var selectedIndex by remember { mutableStateOf(0) }
    val tabContents = listOf(
        "Home" to Icons.Filled.Home,
        "Map" to Icons.Filled.Menu,
        "Settings" to Icons.Filled.Settings
    )

    TabRow(
        divider = {

        },
        selectedTabIndex = selectedIndex,
        containerColor = MaterialTheme.colorScheme.surface,
        contentColor = MaterialTheme.colorScheme.onSurface,
    ) {


        tabContents.forEachIndexed { index, pair: Pair<String, ImageVector> ->
            CustomTab(pair.first, pair.second, {
                selectedIndex = index
            })
        }
    }
}

@Composable
private fun CustomTab(
    title: String,
    icon: ImageVector,
    onClick: () -> Unit,
    modifier: Modifier = Modifier
) {
    Row(
        modifier = modifier
            .clickable(onClick = onClick)
            .padding(16.dp),
        horizontalArrangement = Arrangement.Center,
        verticalAlignment = Alignment.CenterVertically
    ) {
        Icon(
            imageVector = icon,
            contentDescription = null
        )
        Spacer(modifier = Modifier.width(8.dp))
        Text(text = title)
    }
}

@Composable
fun CustomTabs() {
    var selectedIndex by remember { mutableStateOf(0) }

    val list = listOf("Active", "Completed")

    TabRow(selectedTabIndex = selectedIndex,
        containerColor = Color(0xff1E76DA),
        modifier = Modifier
            .padding(vertical = 4.dp, horizontal = 8.dp)
            .clip(RoundedCornerShape(50))
            .background(Color(0xff1E76DA))
            .padding(1.dp),
        indicator = { tabPositions: List<TabPosition> ->
            Box {}
        }
    ) {
        list.forEachIndexed { index, text ->
            val selected = selectedIndex == index
            Tab(
                modifier = if (selected) Modifier
                    .clip(RoundedCornerShape(50))
                    .background(Color.White)
                else Modifier
                    .clip(RoundedCornerShape(50))
                    .background(Color(0xff1E76DA)),
                selected = selected,
                onClick = { selectedIndex = index },
                text = { Text(text = text, color = Color(0xff6FAAEE)) }
            )
        }
    }
}


@Composable
fun ScrollableTextTabComponent() {
    var selectedIndex by remember { mutableStateOf(0) }

    val list = listOf("Home", "Map", "Dashboard", "Favorites", "Explore", "Settings")

    ScrollableTabRow(
        edgePadding = 8.dp,
        selectedTabIndex = selectedIndex
    ) {
        list.forEachIndexed { index, text ->
            Tab(selected = selectedIndex == index,
                onClick = { selectedIndex = index },
                text = { Text(text = text) }
            )
        }
    }
}

@Composable
fun TopAppBarWithTabComponent(onBack: (() -> Unit)? = null) {
    Surface(shadowElevation = 1.dp) {
        Column {
            ActionTopAppbar(onBack, elevation = 0.dp)
            CombinedTabComponent2()
        }
    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ChatAppbar(
    title: String = "Title",
    description: String = "Description",
    onClick: (() -> Unit)? = null,
    onBack: (() -> Unit)? = null
) {
    TopAppBar(
        colors = TopAppBarDefaults.mediumTopAppBarColors(),
        navigationIcon = {
            Row(
                modifier = Modifier
                    .padding(vertical = 4.dp)
                    .clip(RoundedCornerShape(percent = 50))
                    .clickable {
                        onBack?.invoke()
                    },
                verticalAlignment = Alignment.CenterVertically
            ) {

                Icon(
                    imageVector = Icons.Filled.ArrowBack,
                    contentDescription = null
                )

                Surface(
                    modifier = Modifier.padding(6.dp),
                    shape = CircleShape,
                    color = Color.LightGray
                ) {
                    Icon(
                        imageVector = Icons.Filled.Settings,
                        contentDescription = null,

                    )
                }
            }
        },
        title = {
            Column(
                modifier = Modifier
                    .fillMaxHeight()
                    .clickable { onClick?.invoke() }
                    .padding(2.dp),
                verticalArrangement = Arrangement.SpaceEvenly
            ) {
                Text(
                    text = title,
                    fontSize = 16.sp,
                    color = Color.White,
                    fontWeight = FontWeight.Bold,
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis
                )
                CompositionLocalProvider(LocalAlpha provides 0.5f) {
                    Text(
                        description,
                        maxLines = 1,
                        overflow = TextOverflow.Ellipsis
                    )
                }
            }
        }, actions = {
            ChatAppbarActions()
        })
}

@Composable
private fun ChatAppbarActions(
    onCamClick: (() -> Unit)? = null,
    onCallClick: (() -> Unit)? = null
) {
    Row(
        verticalAlignment = Alignment.CenterVertically
    ) {
        IndicatingIconButton(
            onClick = { /* doSomething() */ },
            indication = rememberRipple(bounded = false, radius = 22.dp),
            modifier = Modifier.then(Modifier.size(44.dp))
        ) {
            Icon(
                imageVector = Icons.Rounded.MoreVert,
                contentDescription = null,
                tint = Color.White
            )
        }

        IndicatingIconButton(
            onClick = { /* doSomething() */ },
            indication = rememberRipple(bounded = false, radius = 22.dp),
            modifier = Modifier.then(Modifier.size(44.dp))
        ) {
            Icon(
                imageVector = Icons.Rounded.Call,
                contentDescription = null,
                tint = Color.White
            )
        }

        IndicatingIconButton(
            onClick = { /* doSomething() */ },
            indication = rememberRipple(bounded = false, radius = 22.dp),
            modifier = Modifier.then(Modifier.size(44.dp))
        ) {
            Icon(
                imageVector = Icons.Rounded.MoreVert,
                contentDescription = null,
                tint = Color.White
            )
        }
    }
}


fun Modifier.myTabIndicatorOffset(
    currentTabPosition: TabPosition
): Modifier = composed(
    inspectorInfo = debugInspectorInfo {
        name = "tabIndicatorOffset"
        value = currentTabPosition
    }
) {
    val currentTabWidth by animateDpAsState(
        targetValue = currentTabPosition.width,
        animationSpec = tween(durationMillis = 5250, easing = FastOutSlowInEasing),
        label = "tab width"
    )
    val indicatorOffset by animateDpAsState(
        targetValue = currentTabPosition.left,
        animationSpec = tween(durationMillis = 250, easing = FastOutSlowInEasing),
        label = "indicator offset"
    )
    fillMaxWidth()
        .wrapContentSize(Alignment.BottomStart)
        .offset(x = indicatorOffset)
        .width(currentTabWidth)
}

fun separateIntoActionAndOverflow(
    items: List<ActionItemSpec>,
    defaultIconSpace: Int
): Pair<List<ActionItemSpec>, List<ActionItemSpec>> {

    var (alwaysCount, neverCount, ifRoomCount) = Triple(0, 0, 0)

    for (item in items) {
        when (item.visibility) {
            ActionItemMode.ALWAYS_SHOW -> alwaysCount++
            ActionItemMode.NEVER_SHOW -> neverCount++
            ActionItemMode.IF_ROOM -> ifRoomCount++
        }
    }

    val needsOverflow = alwaysCount + ifRoomCount > defaultIconSpace || neverCount > 0
    val actionIconSpace = defaultIconSpace - (if (needsOverflow) 1 else 0)

    val actionItems = ArrayList<ActionItemSpec>()
    val overflowItems = ArrayList<ActionItemSpec>()

    var ifRoomsToDisplay = actionIconSpace - alwaysCount
    for (item in items) {
        when (item.visibility) {
            ActionItemMode.ALWAYS_SHOW -> {
                actionItems.add(item)
            }

            ActionItemMode.NEVER_SHOW -> {
                overflowItems.add(item)
            }

            ActionItemMode.IF_ROOM -> {
                if (ifRoomsToDisplay > 0) {
                    actionItems.add(item)
                    ifRoomsToDisplay--
                } else {
                    overflowItems.add(item)
                }

            }
        }
    }
    return Pair(actionItems, overflowItems)

}